package com.tensai.study.java.newconcept.typefunctionprogram.base.java_util_function.function;

import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author Tensai
 */
@Slf4j
public class ComposeAndThenTest {

    @Test
    public void test() {
        List<Integer> initData = IntStream.range(0, 20).boxed().collect(Collectors.toList());

        List<Integer> firRet = removeHandler(initData);
        log.info("第一次处理的结果：" + firRet.size());

        List<Integer> secRet = addHandler(firRet);
        log.info("第二次处理的结果：" + secRet.size());

        List<Integer> thirdRet = addHandler(firRet);
        log.info("第三次处理的结果：" + thirdRet.size());

        List<Integer> fourRet = removeHandler(firRet);
        log.info("第四次处理的结果：" + fourRet.size());

        List<Integer> fiveRet = removeHandler(firRet);
        log.info("第五次处理的结果：" + fiveRet.size());
    }

    @Test
    public void test0() {
        List<Integer> initData = IntStream.range(0, 20).boxed().collect(Collectors.toList());

        Function<List<Integer>, List<Integer>> remove = this::removeHandler;
        Function<List<Integer>, List<Integer>> add = this::addHandler;

        List<Integer> result = add.compose(remove)
                .andThen(add)
                .andThen(remove)
                .andThen(remove)
                .apply(initData);
        log.info("调整后的：" + result);
    }

    private @NotNull List<Integer> removeHandler(List<Integer> dataList) {
        // 每次随机删除几个数
        log.info("删除一些数据。。");
        return handler(
                (i, list) -> {
                    log.info("DEL {} - {}", i, list);
                    list.remove(i);
                },
                dataList);
    }


    private @NotNull List<Integer> addHandler(List<Integer> dataList) {
        // 每次随机增加几个数，
        log.info("增加一些数据。。");
        return handler(
                (i, list) -> {
                    log.info("ADD {} - {}", i, list);
                    list.add(i);
                },
                dataList);
    }


    private @NotNull List<Integer> handler(BiConsumer<Integer, List<Integer>> consumer, List<Integer> dataList) {
        List<Integer> handList = new ArrayList<>(dataList);
        // 处理逻辑，每次随机处理几个数据
        IntStream.range(0, getRandom(5))
                .boxed()
                .forEach(i -> consumer.accept(getRandom(handList.size()), handList));

        // 错误数据可以自行处理，这里返回的是成功的数据
        return handList;
    }

    private @NotNull Integer getRandom(Integer size) {
        return new Random().nextInt(size);
    }
}
